import {getIpMacAddress, rand, uuid} from "./utils";
import AppConfig from "../../config/app.config";
import * as CryptoJS from 'crypto-js';
import {ApplyStatus, ApproveStatus, ResCode} from "./constants";
import {CommonResponseDto} from "../dto/common.response.dto";
import {CommonRedisService} from "../service/common.redis.service";
import {CommonRequestService} from "../service/common.request.service";

const fs = require('fs'); // 导入 fs 模块
const path = require('path'); // 导入 path 模块
export const mkdir = (pathname: string) => {
    if (!fs.existsSync(pathname)) {
        fs.mkdirSync(pathname)
    }
}
export const copyDir = (originPath: string, targetPath: string) => {
    fs.readdir(originPath,{withFileTypes:true},(err,files)=>{
        for(let file of files){
            //判断是否是文件夹，不是则直接复制文件到newFile中
            if(!file.isDirectory()){
                //获取旧文件夹中要复制的文件
                const OriginFile = path.resolve(originPath,file.name)
                //获取新文件夹中复制的地方
                const CopyFile = path.resolve(targetPath,file.name)
                //将文件从旧文件夹复制到新文件夹中
                fs.copyFileSync(OriginFile,CopyFile)
            }else{//如果是文件夹就递归变量把最新的文件夹路径传过去
                const CopyDirPath = path.resolve(targetPath,file.name)
                const OriginDirPath = path.resolve(originPath,file.name)
                fs.mkdir(CopyDirPath,(err)=>{

                })
                // OriginFilePath = OriginPath
                // CopyFilePath = DirPath
                copyDir(OriginDirPath,CopyDirPath)
            }
        }
    })
}
export const listToTree = (list, childrenKey: string = 'children', itemIdKey: string = 'id', parentIdKey: string = 'parentId', parentId?: string) => {
    let menuObj = {}
    list.forEach(item => {
        item[childrenKey] = []
        menuObj[item[itemIdKey]] = item
    })
    return list.filter(item => {
        if (item[parentIdKey] !== parentId) {
            menuObj[item[parentIdKey]][childrenKey].push(item)
            return false
        }
        return true
    })
}
export const getDingDingHeaders = (method: string, api: string, query: any = {}) => {
    const {ip, mac} = getIpMacAddress()
    const date = new Date()
    const ts = date.getTime()
    // 请求必须加8个小时，否则匹配不上
    const secondTs = Number(ts.toString().replace(/\d{3}$/, '')) + 28800
    let tsUTC = new Date(secondTs*1000).toISOString().replace('Z', '+08:00')
    let nonce = `${secondTs*1000}${rand(1000, 9999)}`
    const keys = Object.keys(query).sort()
    const paramsStrArr = []
    const getVal = (k: string, obj: any) => {
        let str = ''
        const val = obj[k]
        if (Object.prototype.toString.call(val) === '[object Object]') {
            str = `${k}={`
            Object.keys(val).sort().forEach((s: string) => {
                str += getVal(s, val)
            })
            str += '}'
        } else {
            str = `${k}=${obj[k]}`
        }
        return str
    }
    keys.forEach((k: string) => {
        const val = query[k]
        if (Object.prototype.toString.call(val) === '[object Object]') {
            paramsStrArr.push(`${k}=${JSON.stringify(val)}`)
        } else {
            paramsStrArr.push(`${k}=${val}`)
        }
    })
    let signStr
    if (paramsStrArr.length) {
        signStr = `${method.toLocaleUpperCase()}\n${tsUTC}\n${nonce}\n${api}\n${paramsStrArr.join('&')}`
    } else {
        signStr = `${method.toLocaleUpperCase()}\n${tsUTC}\n${nonce}\n${api}`
    }
    const hash = CryptoJS.HmacSHA256(signStr, AppConfig.DingDing.AppSecret);
    // 将签名转换为Base64编码的字符串
    const base64Signature = hash.toString(CryptoJS.enc.Base64);
    const headers = {
        'X-Hmac-Auth-IP': ip,
        'X-Hmac-Auth-MAC': mac,
        'X-Hmac-Auth-Timestamp': tsUTC,
        'X-Hmac-Auth-Version': '1.0',
        'X-Hmac-Auth-Nonce':nonce,
        'apiKey': AppConfig.DingDing.AppKey,
        'X-Hmac-Auth-Signature': base64Signature
    }
    console.log(headers)
    return headers
}

export const getAccessToken = async (commonRedisService: CommonRedisService, commonRequestService: CommonRequestService) => {
    try {
        let localAccessToken = await commonRedisService.get(AppConfig.DingDing.AccessTokenKey)
        if (localAccessToken) {
            return localAccessToken
        }
        const api = '/gettoken.json'
        const headers = getDingDingHeaders('post', api, {})
        const result = await commonRequestService.post(`${AppConfig.DingDing.Domain}${api}`, {
            appkey: AppConfig.DingDing.AppKey,
            appsecret: AppConfig.DingDing.AppSecret
        }, {
            headers,
        })
        console.log('getAccessToken', result)
        if (result.content && result.content.data) {
            const { expiresIn, accessToken } = result.content.data
            await commonRedisService.set(AppConfig.DingDing.AccessTokenKey, accessToken, expiresIn)
            return accessToken
        }
        return null
    } catch(e){
        console.log(e)
        return null
    }
}
const msgApi = '/message/workNotification'
export const sendApproveMsg = async (accountId: string, msg: string[], params: {type: string, status: number, id?: string, }, {commonRedisService, commonRequestService}: {commonRedisService: CommonRedisService, commonRequestService: CommonRequestService}) => {
    const token = await getAccessToken(commonRedisService, commonRequestService)
    console.log('token', token)
    let jumpUrl = ''
    if (params.type === 'my') {
        jumpUrl = "taurus://taurusclient/action/open_app?appId=0240812172047825&type=2&offline=false&page=%2Fpages%2Fmy%2Fmy&query=tab%3D"+params.status
    }
    if (params.type === 'approve') {
        jumpUrl = "taurus://taurusclient/action/open_app?appId=0240812172047825&type=2&offline=false&page=%2Fpages%2Fapprove%2Fapprove&query=tab%3D1%3Did="+params.id
    }
    const query = {
        organizationCodes: '',
        receiverIds: accountId,
        tenantId: 50805445,
        bizMsgId: uuid(32),
        // msg: {
        //     "msgtype": "link",
        //     "link": {
        //         "messageUrl": jumpUrl,
        //         "picUrl":"@lALOACZwe2Rk",
        //         "title": "审批通知",
        //         "text": msg.join('；')
        //     }
        // },
        msg: params.type === 'approve' ? {
            "msgtype": "action_card",
            "action_card": {
                "title": "待审批通知",
                "markdown": msg.join('\n'),
                "statusInfo": {
                    "text": "待审批",
                    "bgcolor": "#FF9F00",
                    "allcolor": "rgba(31, 31, 31)"
                },
                "btn_orientation": "1",
                "btn_json_list": [
                    {
                        "title": "拒绝",
                        "action_pc_url": jumpUrl + "%3Dstatus=2",
                        "action_mobile_url": jumpUrl + "%3Dstatus=2"
                    },
                    {
                        "title": "同意",
                        "action_pc_url": jumpUrl + "%3Dstatus=1",
                        "action_mobile_url": jumpUrl + "%3Dstatus=1"
                    }
                ]
            }
        } : {
            "msgtype": "action_card",
            "action_card": {
                "title": "审批通知",
                "markdown": msg.join('\n'),
                "single_title": "点击查看",
                "single_url": jumpUrl,
                "single_pc_url": jumpUrl
            }
        }
    }
    const headers = getDingDingHeaders('get', msgApi, query)
    try {
        const result = await commonRequestService.get(`${AppConfig.DingDing.Domain}${msgApi}`, {
            headers,
            params: query
        })
        if (result.success) {
            return new CommonResponseDto(ResCode.OK, '成功', result)
        }
        return new CommonResponseDto(ResCode.ERROR, '失败', result)
    } catch(e){
        console.log(e)
        return new CommonResponseDto(ResCode.ERROR, '服务异常', null)
    }
}
